/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.compomics.dataprovider.view.suite.panels.filetable;

import com.compomics.dataprovider.control.logic.fasta.FastaSourceConverter;
import com.compomics.dataprovider.model.fasta.FastaStream;
import com.compomics.dataprovider.view.suite.FastaProviderSuite;
import com.compomics.dataprovider.view.suite.model.FastaRepositoryProperties;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import org.apache.commons.io.FileUtils;

/**
 *
 * @author Kenneth
 */
public class FastaFileTablePopupMenu extends JPopupMenu implements ActionListener {

    private final JMenuItem menuItemAddDecoys = new JMenuItem("Add Decoys");
    private final JMenuItem menuItemMergeFiles = new JMenuItem("Merge Files");
    private final JMenuItem menuItemRemove = new JMenuItem("Delete file");
    private final JMenuItem menuItemRename = new JMenuItem("Rename file");
    private final JMenuItem menuItemAddcRAP = new JMenuItem("Add cRAP database");
    private final JMenuItem menuItemClean = new JMenuItem("Clean");
    private final FastaFileTable table;
    private boolean append;
    private File destination;

    public FastaFileTablePopupMenu(FastaFileTable table) {
        super();
        this.table = table;
        init();
        add(menuItemClean);
        add(menuItemAddcRAP);
        add(menuItemAddDecoys);
        add(menuItemMergeFiles);
        add(menuItemRename);
        add(menuItemRemove);

    }

    private void init() {
        menuItemAddDecoys.addActionListener(this);
        menuItemAddcRAP.addActionListener(this);
        menuItemMergeFiles.addActionListener(this);
        menuItemRename.addActionListener(this);
        menuItemRemove.addActionListener(this);
        menuItemClean.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        JMenuItem menu = (JMenuItem) event.getSource();

        if (menu == menuItemClean) {
            try {
                cleanSelection();
            } catch (IOException ex) {
                Logger.getLogger(FastaFileTablePopupMenu.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else if (menu == menuItemAddDecoys) {
            try {
                addDecoys();
            } catch (IOException ex) {
                Logger.getLogger(FastaFileTablePopupMenu.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else if (menu == menuItemAddcRAP) {
            try {
                addcRAP();
            } catch (IOException ex) {
                Logger.getLogger(FastaFileTablePopupMenu.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else if (menu == menuItemMergeFiles) {
            try {
                mergeFiles();
            } catch (IOException ex) {
                Logger.getLogger(FastaFileTablePopupMenu.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else if (menu == menuItemRename) {
            try {
                renameCurrentRow();
            } catch (IOException ex) {
                Logger.getLogger(FastaFileTablePopupMenu.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else if (menu == menuItemRemove) {
            try {
                removeCurrentRows();
            } catch (IOException ex) {
                Logger.getLogger(FastaFileTablePopupMenu.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        try {
            FastaProviderSuite.getInstance().reload();
        } catch (IOException ex) {
            Logger.getLogger(FastaFileTablePopupMenu.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void addDecoys() throws IOException {
        int selectedRow = table.getSelectedRow();
        File originalFile = getFile(selectedRow);
        promptUser(originalFile);
        FastaStream stream = new FastaStream(FastaSourceConverter.convertToStream(originalFile));
        stream.addDecoys();
        stream.save(destination, append);
    }

    private void addcRAP() throws IOException {
        int selectedRow = table.getSelectedRow();
        File originalFile = getFile(selectedRow);
        promptUser(originalFile);
        FastaStream stream = new FastaStream(FastaSourceConverter.convertToStream(originalFile));
        stream.appendCRAP();
        stream.save(destination, append);
    }

    private void mergeFiles() throws IOException {
        DefaultTableModel model = (DefaultTableModel) table.getModel();
        File file = new File(FastaRepositoryProperties.getRepositoryPath() + "/merged/do_not_touch.fasta");
        promptUser(file);
        if (!destination.exists()) {
            destination.getParentFile().mkdirs();
            destination.createNewFile();
        }
        FastaStream output = new FastaStream(FastaSourceConverter.convertToStream(destination));
        int rowCount = model.getRowCount();
        for (int i = 0; i < rowCount; i++) {
            output.concatenate(getFile(i));
        }
        output.save(destination, append);
    }

    private void cleanSelection() throws IOException {
        int selectedRow = table.getSelectedRows()[0];
        File file = getFile(selectedRow);
        FastaStream stream = new FastaStream(FastaSourceConverter.convertToStream(file));
        stream.removeDuplicateAccessions().removeDuplicateSequences().save(file, false);
    }

    private void renameCurrentRow() throws IOException {
        int selectedRow = table.getSelectedRows()[0];
        renameEntry(selectedRow);
    }

    private void removeCurrentRows() throws IOException {
        int dialogResult = JOptionPane.showConfirmDialog(null,
                "Are you sure you want to delete the selected file(s)?\n"
                + "Proceed?", "This action can not be undone", JOptionPane.YES_NO_OPTION);
        if (dialogResult == JOptionPane.YES_OPTION) {
            int[] rows = this.table.getSelectedRows();
            for (int i = 0; i < rows.length; i++) {
                removeEntry(rows[i] - i);
            }
        }
    }

    private boolean promptUser(File originalFile) {
        boolean cancelled = true;
        String filename = getUserInput(originalFile.getName());
        if (filename != null) {
            destination = new File(originalFile.getParentFile(), filename + ".fasta");
            if (destination.exists()) {
                String[] options = new String[]{"Append", "Override", "Cancel"};
                int response = JOptionPane.showOptionDialog(null, "Message", "Title",
                        JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE,
                        null, options, options[0]);
                switch (response) {
                    case 0:
                        append = true;
                        cancelled = false;
                        break;
                    case 1:
                        append = false;
                        cancelled = false;
                        break;
                }
            }
        }
        return cancelled;
    }

    private String getUserInput(String originalFileName) {
       String returnString="";
        JTextField inputField = new JTextField();
        inputField.setText(originalFileName.replace(".fasta","").replace(".FASTA",""));
        Object[] message = {
            "New name:", inputField,};
        int confirm =JOptionPane.showConfirmDialog(null, message, "Import", JOptionPane.OK_CANCEL_OPTION);
        if(confirm==JOptionPane.OK_OPTION){
        returnString = inputField.getText();
        }
        return returnString;
    }

    private File getFile(int row) {
        DefaultTableModel model = (DefaultTableModel) table.getModel();
        String fileName = String.valueOf(model.getValueAt(row, 0));
        return table.getFiles().get(fileName);
    }

    private boolean removeEntry(int row) throws IOException {
        File toRemove = getFile(row);
        return removeFileFromRepository(toRemove);
    }

    private void renameEntry(int row) throws IOException {
        // File (or directory) with old name
        File file = getFile(row);
        // File (or directory) with new name
        File file2 = new File(file.getParentFile(), getUserInput(file.getName()) + ".fasta");
        if (file2.exists()) {
            throw new java.io.IOException("file exists");
        }
        // Rename file (or directory)
        boolean success = file.renameTo(file2);
        if (success) {
            removeFileFromRepository(file);
        }
    }

    private boolean removeFileFromRepository(File toRemove) throws IOException {
        boolean deleted = toRemove.delete();
        if (deleted) {
            if (toRemove.getParentFile().listFiles().length == 0) {
                try {
                    FileUtils.deleteDirectory(toRemove.getParentFile());
                } catch (IOException e) {
                    System.out.println("Could not delete parentfolder");
                }
            }
            FastaProviderSuite.getInstance().reload();
        }
        return deleted;
    }

}
